package org.duang.core;

import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHeaders;
import org.duang.common.dto.HeadDto;
import org.duang.common.dto.ReturnDto;
import org.duang.common.enums.IEnums;
import org.duang.common.exceptios.ServiceException;
import org.duang.config.Config;
import org.duang.config.InstanceFactory;
import org.duang.db.annotation.Vo;
import org.duang.db.annotation.VoColl;
import org.duang.http.util.HttpUtil;
import org.duang.ioc.Ignore;
import org.duang.kit.ClassKit;
import org.duang.kit.DataType;
import org.duang.kit.Encodes;
import org.duang.kit.OSSKit;
import org.duang.kit.ObjectKit;
import org.duang.kit.ToolsKit;
import org.duang.render.FileRender;
import org.duang.render.JsonRender;
import org.duang.render.JspRender;
import org.duang.render.RedirectRender;
import org.duang.render.Render;
import org.duang.render.TextRender;
import org.duang.render.XmlRender;
import org.duang.token.TokenManager;
import org.duang.upload.UploadFile;
import org.duang.upload.UploadFileRequest;
import org.duang.vtor.core.VtorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public abstract class Controller {

	private static Logger logger = LoggerFactory.getLogger(Controller.class);
	private HttpServletRequest request;
	private HttpServletResponse response;
	private Render render;
	private static Map<String, Object> attribValueMap = new ConcurrentHashMap<String, Object>();
	private static final String contentJsonType = "application/json";
	private static final String contentDataType = "multipart/form-data";
	private static final String xwwwformurlencodedType = "application/x-www-form-urlencoded";
	private static final String[] TerminalArray = {"Android", "iPhone", "iPad"};
	private static final String DUANG_INPUTSTREAM_NAME = "dunag_inputstream";

	public void init(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
		fillStream2Request();
		if (Config.getDebug()) {
			printRequest();
		}
	}

	private void printRequest() {
		System.out.println("******************************************************************************");
		System.out.println("###########RequestDate:   " + ToolsKit.formatDate(getRequestDate(), Config.getDefaultDateFormat()));
		System.out.println("###########RequestHeader: " + request.getHeader(HttpHeaders.USER_AGENT));
		System.out.println("###########RequestURL:    " + request.getRequestURL());
		System.out.println("###########RemoteMethod:  " + request.getMethod());
		System.out.println("###########RequestValues: " + JSON.toJSONString(getAllParams()));
		System.out.println("******************************************************************************");
	}

	private Date getRequestDate() {
		String d = request.getHeader(HttpHeaders.DATE);
		if (ToolsKit.isEmpty(d))
			return new Date();
		try {
			return new Date(Long.parseLong(d));
		} catch (Exception e) {
			return ToolsKit.parseDate(d, Config.getDefaultDateFormat());
		}
	}

	public Render getRender() {
		return render;
	}

	private Map<String, Object> getAllParams() {
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, String[]> requestParams = request.getParameterMap();
		if (ToolsKit.isNotEmpty(requestParams)) {
			for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
				}
				params.put(name, valueStr);
			}
		}
		if (ToolsKit.isNotEmpty(attribValueMap))
			params.putAll(attribValueMap);
		return params;
	}

	/**
	 * 返回JSON格式字符串
	 * 
	 * @param obj
	 */
	private void returnJson(Object obj) {
		render = new JsonRender(obj);
	}

	/**
	 * 返回指定路径的页面
	 * 
	 * @param view
	 *            路径
	 * @param pageExtName
	 *            页面扩展名
	 */
	private void returnPage(String view, String pageExtName) {
		render = new JspRender(view, pageExtName);
	}

	public void returnText(String text) {
		render = new TextRender(text);
	}

	public void returnXml(String text) {
		render = new XmlRender(text);
	}

	/**
	 * 下载文件
	 * 
	 * @param file
	 *            UploadFile对象
	 * @throws Exception
	 */
	public void download(File file) throws Exception {
		render = new FileRender(file);
	}

	public void download(UploadFile file) throws Exception {
		render = new FileRender(file);
	}

	/**
	 * 不带参数重定向到页面，
	 * 
	 * @param 重定向到的URL
	 */
	private void redirectPage(String url, boolean withQueryString) {
		render = new RedirectRender(url);
	}
	
	/**
	 * ############################### 以下为扩展方法 ###############################
	 */

		/**
	 * 取得Request
	 * 
	 * @return
	 */
	public HttpServletRequest getRequest() {
		return request;
	}

	/**
	 * 取得Response
	 * 
	 * @return
	 */
	public HttpServletResponse getReqsponse() {
		return response;
	}

	public Controller setValue(String key, Object obj) {
		request.setAttribute(key, obj);
		return this;
	}

	public Controller setSessionValue(String key, Object value) {
		request.getSession().setAttribute(key, value);
		return this;
	}

	@SuppressWarnings("unchecked")
	public <T> T getSessionValue(String key) {
		HttpSession session = request.getSession();
		return session != null ? (T) session.getAttribute(key) : null;
	}

	public Controller removeSessionValue(String key) {
		HttpSession session = request.getSession(false);
		if (session != null)
			session.removeAttribute(key);
		return this;
	}

	/**
	 * 取出请求值
	 * 
	 * @param key
	 *            请求参数的key
	 * @return 如果存在则返回字符串内容,不存在则返回""
	 */
	public String getValue(String key) {
		String values = "";
		try {
			values = request.getParameter(key);
			if (ToolsKit.isEmpty(values)) {
				values = ToolsKit.isEmpty(request.getAttribute(key)) ? "" : request.getAttribute(key).toString();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return values;
	}
	
	private Object getValueObj(String key) {
		Object values = null;
		try {
			values = request.getParameter(key);
			if (null == values) {
				values = request.getAttribute(key);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return values;
	}

	/**
	 * 取出请求值
	 * 
	 * @param key
	 *            请求参数的key
	 * @return 如果存在则返回字符串内容,不存在则返回null
	 */
	public String[] getValues(String key) {
		String[] values = null;
		try {
			values = request.getParameterValues(key);
			if (ToolsKit.isEmpty(values)) {
				values = ToolsKit.isEmpty(request.getAttribute(key)) ? null : (String[]) request.getAttribute(key);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return values;
	}

	/**
	 * 是否分页请求
	 * 
	 * @return true 为分页请求
	 */
	public boolean isPagination() {
		return ToolsKit.isNotEmpty(this.getValue("_mvcpage"));
	}
	
	private boolean isJsonString(String str){
		if(ToolsKit.isEmpty(str)) return false;
		return str.trim().startsWith("{") && str.trim().endsWith("}") && (request.getContentType().indexOf(contentJsonType.toLowerCase()) >  -1) ? true : false;
	}

	@SuppressWarnings("unchecked")
	private void fillStream2Request() {
		attribValueMap.clear();
		
		String str = stream2Str();
		if (ToolsKit.isEmpty(str))
			return;
		Map<String, Object> valueMap = null;
		boolean isJsonString = isJsonString(str); 
		try {
			if (isJsonString) {
				valueMap = JSON.parseObject(str, Map.class);
				isJsonString = true;
			}
		} catch (Exception e) {
			logger.warn(str + " is not JSON String!");
		}
		if (isJsonString) {
			String tokenid = (String) valueMap.get("tokenid");
			JSONObject dataObj = (JSONObject) valueMap.get("data");
			if (ToolsKit.isNotEmpty(tokenid)) {
				attribValueMap.put("tokenid", tokenid);
				request.setAttribute("tokenid", tokenid);
			}
			if (ToolsKit.isNotEmpty(dataObj)) {
				jsonObjectFill2Request(dataObj.entrySet());
			} else {
				jsonObjectFill2Request(valueMap.entrySet());
			}
		} else {
			valueMap = HttpUtil.parseUrlParam2Map(str);
			for (Iterator<Entry<String, Object>> it = valueMap.entrySet().iterator(); it.hasNext();) {
				Entry<String, Object> entry = it.next();
				String name = entry.getKey();
				Object value = entry.getValue();
				request.setAttribute(name, ToolsKit.isEmpty(value) ? "" : value);
				attribValueMap.put(name, ToolsKit.isEmpty(value) ? "" : value);
			}
		}
	}
	
	private void jsonObjectFill2Request(Set<Entry<String, Object>> entrySet) {
		for (Entry<String, Object> entry : entrySet) {
			String name = entry.getKey();
			Object value = entry.getValue();
			attribValueMap.put(name, value);
			request.setAttribute(name, ToolsKit.isEmpty(value) ? "" : value);
		}
	}

	private String stream2Str() {
		InputStream is = null;
		String str = "";
		try {
			if(ToolsKit.isEmpty(request.getContentType())
					|| request.getContentType().toLowerCase().indexOf(contentDataType) > -1
					|| request.getContentType().toLowerCase().indexOf(xwwwformurlencodedType) > -1)  
				return str;		//如果是文件提交或普通表单提交的话就直接退出
			is = request.getInputStream();
			if (ToolsKit.isNotEmpty(is)) {
				str = IOUtils.toString(is, Config.getEncoding());
				is = IOUtils.toInputStream(str, Config.getEncoding());
//				OutputStream os = new java.io.ByteArrayOutputStream();
//				if(ToolsKit.isNotEmpty(is)){
//					IOUtils.copy(is, os);
//				}
				request.setAttribute(DUANG_INPUTSTREAM_NAME, is);
			}
			
			// boolean isAjax = request.getHeader("X-Requested-With") != null &&
			// request.getHeader("X-Requested-With").equals("XMLHttpRequest");
			// boolean isJson = request.getContentType() != null &&
			// request.getContentType().indexOf(contentJsonType.toLowerCase()) >
			// -1;
			// if(isJson || isAjax ){
			// is = request.getInputStream();
			// json = IOUtils.toString(is, Config.getEncoding());
			// }
		} catch (IOException e) {
			logger.error("Controller.stream2Str() fail: " + e.getMessage() + " return null...", e);
		} finally {
			IOUtils.closeQuietly(is);
		}
		logger.debug(str);
		return str;
	}

	public String getXml() {
		InputStream is = null;
		String xml = "";
		try {
			is =getInputStream();
			xml = IOUtils.toString(is, Config.getEncoding());
		} catch (IOException e) {
			logger.error("Controller.getJson() fail: " + e.getMessage() + " return null...", e);
			return null;
		} finally {
			IOUtils.closeQuietly(is);
		}
		return ToolsKit.isEmpty(xml) ? null : xml;
	}
	
	public InputStream getInputStream() {
		return  (InputStream)request.getAttribute(DUANG_INPUTSTREAM_NAME);
//		InputStream is = null;
//		ByteArrayOutputStream out= null;
//		try {
//			out= (ByteArrayOutputStream)request.getAttribute(DUANG_INPUTSTREAM_NAME);
//			if(null != out) {
//				is = new ByteArrayInputStream(out.toByteArray()) ;
//			}
//		} catch (Exception e) {
//			logger.error("Controller.getInputStream() fail: " + e.getMessage() + " return null...", e);
//		} finally {
//			IOUtils.closeQuietly(out);
//		}
//		return is;
	}

	/**
	 * 根据clazz创建Dto对象
	 * 
	 * @param clazz
	 *            要创建的Dto calss
	 * @return Dto
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public <T> T parseJson2Object(Class<T> typeReference) throws Exception {
		String jsonStr = IOUtils.toString(getInputStream(), Config.getEncoding());
		if (ToolsKit.isEmpty(jsonStr))
			return null;
//		int indexOf = StringUtils.indexOfIgnoreCase(jsonStr, "tokenid");
//		int end = (indexOf == -1) ? jsonStr.length()  :  (indexOf < 10) ? jsonStr.length() - 1 : indexOf - 2;
//		int start = StringUtils.indexOfIgnoreCase(jsonStr, "data");
//		start = (start == -1) ? 0 : start +6;
//		jsonStr = StringUtils.substring(jsonStr, start, end);
		
		boolean isJsonString = this.isJsonString(jsonStr);
		if(isJsonString){
			Map<String, Object> valueMap = JSON.parseObject(jsonStr, Map.class);
			String tokenid = (String) valueMap.get("tokenid");
			JSONObject dataObj = (JSONObject) valueMap.get("data");
			if(ToolsKit.isNotEmpty(dataObj)){
				jsonStr = dataObj.toJSONString();
			}
			if(ToolsKit.isNotEmpty(tokenid)){
				request.setAttribute("tokenid", tokenid);
			}
		} else {
			throw new ServiceException();
		}
		
		try{
			return JSON.parseObject(jsonStr, typeReference);
		}catch(Exception e){
			try{
			return getBean(typeReference);
			}catch(Exception ex){
				logger.warn(ex.getMessage(), ex);
				throw ex;
			}
		}
	}

	public Map<String, Object> getAllValue() {
		Map<String, Object> paramMap = new ConcurrentHashMap<String, Object>();
		Enumeration<String> enumer = request.getParameterNames();
		if (ToolsKit.isNotEmpty(enumer)) {
			while (enumer.hasMoreElements()) {
				String key = enumer.nextElement();
				String value = getValue(key);
				paramMap.put(key, value);
			}
		}
		enumer = request.getAttributeNames();
		if (ToolsKit.isNotEmpty(enumer)) {
			while (enumer.hasMoreElements()) {
				String key = enumer.nextElement();
				String value = getValue(key);
				paramMap.put(key, value);
			}
		}
		enumer = request.getSession().getAttributeNames();
		if (ToolsKit.isNotEmpty(enumer)) {
			while (enumer.hasMoreElements()) {
				String key = enumer.nextElement();
				Object value = getSessionValue(key);
				paramMap.put(key, value);
			}
		}
		return paramMap;
	}

	protected void returnPage(String viewPath) {
		int pos = viewPath.lastIndexOf(".");
		String extname = ".jsp";
		if (viewPath.lastIndexOf(".") > -1) {
			extname = viewPath.substring(pos, viewPath.length());
			viewPath = viewPath.substring(0, pos);
		}
		returnPage(viewPath, extname);
	}

	protected void returnSuccessJson(Object obj) {
		returnSuccessJson(null, obj);
	}

	protected void returnSuccessJson(IEnums enums, Object obj) {
		returnJson(ToolsKit.buildReturnDto(enums, obj));
	}

	protected void redirect(String methodName) {
		this.redirect(methodName, false);
	}

	protected void redirect(String methodName, boolean withQueryString) {
		this.redirect(getClass(), methodName, withQueryString);
	}

	protected void redirect(Class<? extends Controller> clazz, String methodName) {
		this.redirect(clazz, methodName, false);
	}

	protected void redirect(Class<? extends Controller> clazz, String methodName, boolean withQueryString) {
		String actionKey = getMethodMappingKey(clazz, methodName);
		redirectPage(actionKey, withQueryString);
	}

	private String getMethodMappingKey(Class<? extends Controller> clazz, String methodName) {
		String mappingKey = "";
		for (Iterator<Entry<String, Action>> it = InstanceFactory.getActionMapping().entrySet().iterator(); it
				.hasNext();) {
			Entry<String, Action> entry = it.next();
			Action action = entry.getValue();
			if (ToolsKit.isNotEmpty(action) && ToolsKit.isNotEmpty(action.getControllerClass())
					&& action.getControllerClass().equals(clazz)) {
				if (action.getMethod().getName().equals(methodName)) {
					mappingKey = action.getActionKey();
					break;
				}
			}
		}
		return mappingKey;
	}

	/**
	 * 返回错误信息到客户端
	 * 
	 * @param se
	 *            自定义ServiceException异常
	 */
	protected void returnFailJson(Exception ex) {
		String message = ex.getMessage();
		int code = IEnums.IENUMS_FAIL_CODE;
		if (ex instanceof ServiceException) {
			ServiceException se = (ServiceException) ex;
			IEnums enums = se.getEnums();
			if (ToolsKit.isEmpty(enums)) {
				code = ToolsKit.isEmpty(se.getCode()) ? IEnums.IENUMS_FAIL_CODE : se.getCode();
				message = ToolsKit.isEmpty(se.getMessage()) ? IEnums.IENUMS_FAIL_MESSAGE : se.getMessage();
			} else {
				code = enums.getCode();
				message = enums.getMessage();
			}
			System.err.println("returnFail：" + se.getStackTrace()[0].getClassName() + "-->"
					+ se.getStackTrace()[0].getMethodName() + "-->" + se.getStackTrace()[0].getLineNumber() + "："
					+ message + "：" + request.getRequestURI() + "：" + JSON.toJSONString(this.getAllValue()));
		} else {
			logger.error(ex.getMessage(), ex);
		}
		ReturnDto<Map<String, Object>> dto = new ReturnDto<Map<String, Object>>();
		HeadDto head = new HeadDto();
		head.setRet(code);
		head.setMsg(message);
		head.setUri(request.getRequestURI());
		dto.setHead(head);
		dto.setData(getAllValue());
		returnJson(dto);
	}

	protected void returnFailJson(IEnums enums) {
		returnFailJson(enums, "");
	}

	protected void returnFailJson(Object obj) {
		returnJson(obj);
	}

	protected void returnFailJson(IEnums enums, String message) {
		ReturnDto<Map<String, Object>> dto = new ReturnDto<Map<String, Object>>();
		HeadDto head = new HeadDto();
		head.setRet(enums.getCode());
		head.setMsg(ToolsKit.isEmpty(message) ? enums.getMessage() : message);
		head.setUri(request.getRequestURI());
		dto.setHead(head);
		dto.setData(getAllValue());
		returnJson(dto);
	}

	protected List<UploadFile> getUploadFiles(String saveDirectory) {
		UploadFileRequest uploadFileRequest = new UploadFileRequest(request, saveDirectory);
		request = uploadFileRequest;
		List<UploadFile> files = uploadFileRequest.getUploadFiles();
		if ("OSS".equalsIgnoreCase(Config.getUploadFileSite())) {
			OSSKit.putImg2OSS(files);
		}
		return files;
	}

	public List<UploadFile> getUploadFiles() {
		return getUploadFiles(null);
	}

	public UploadFile getUploadFile(String saveDirectory) {
		List<UploadFile> uploadFiles = getUploadFiles(saveDirectory);
		return uploadFiles.size() > 0 ? uploadFiles.get(0) : null;
	}

	public UploadFile getUploadFile() {
		return getUploadFile(null);
	}

	/**
	 * 根据提交的参数，自动填充Entity, 默认开启验证
	 * 
	 * @param cls
	 *            Class
	 * @return
	 */
	public <T> T getBean(Class<T> cls) throws Exception {
		return getBean(cls, "", true);
	}
	
	/**
	 * 根据提交的参数，自动填充Entity, 是否开启验证
	 * @param cls				要自动填充的class
	 * @param isVtor			是否开启验证
	 * @return
	 */
	public <T> T getBean(Class<T> cls, boolean isVtor) throws Exception {
		return getBean(cls, "", isVtor);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private <T> T getBean(Class<T> cls, String fieldName, boolean isVtor) {
		Object obj = ObjectKit.newInstance(cls);
		Field[] fields = ClassKit.getFields(cls);
		if (ToolsKit.isNotEmpty(fields)) {
			try {
				for (Field field : fields) {
					String key = (ToolsKit.isNotEmpty(fieldName)) ? fieldName + "." : "";
					key += field.getName();
					if (field.isAnnotationPresent(Vo.class)) {
						T vo = (T) getBean(field.getType(), key, isVtor);
						fillBean(obj, field, vo);
					} else if (field.isAnnotationPresent(VoColl.class)) {
						 Object value = ObjectKit.getFieldValue(obj, field);
						if(field.getType().isArray()){
							List<Object> result = fillArray(value, field, key, isVtor);
							fillBean(obj, field, result);
						} else {
							ParameterizedType paramType = (ParameterizedType)field.getGenericType();
							Type[] paramTypes = paramType.getActualTypeArguments();
							Map result = null;
							if (paramTypes.length == 2){
								result = fillMap(value, field, key, isVtor);
							}
							fillBean(obj, field, result);
						}
					} else {
						fillBean(obj, field, key);
					}
				}
				if(isVtor){
					// 验证javabean是否符合规则
					VtorFactory.validator(obj);
				}
			} catch (Exception e) {
				logger.warn(e.getMessage(), e);
				throw new ServiceException(e);
			}
		}
		return (T) obj;
	}
	
	private List<Object> fillArray(Object value, Field field, String key, boolean isVtor) {
		int length = Array.getLength(value);
		List<Object> result = new ArrayList<Object>(length);
		for (int i = 0; i < length; i++) {
			Object objTmp = Array.get(value, i);
			if(null != objTmp){
				result.add(getBean(field.getType(), key, isVtor));
			}
		}
		return result;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Map fillMap(Object value, Field field, String key, boolean isVtor) {
		Map map = (Map)value;
		Map result = new HashMap(map.size());
		for(Iterator<String> it = map.keySet().iterator(); it.hasNext();){
			String keyTmp = it.next();
			Object obj = map.get(keyTmp);
			if(ToolsKit.isNotEmpty(obj)){
				result.put(keyTmp,  getBean(field.getType(), key, isVtor));
			} else {
				result.put(keyTmp, null);
			}
		}
		return result;
	}

	private void fillBean(Object obj, Field field, Object vo) {
		ObjectKit.setField(obj, field.getName(), vo);
	}

	@SuppressWarnings("rawtypes")
	private void fillBean(Object obj, Field field, String key) {
		Class<?> typeCls = field.getType();
		String fieldName = field.getName();
		Object tmpObj = getValueObj(key);
		if (typeCls.equals(String.class)) {
			if (ToolsKit.isEmpty(tmpObj)) {
				printFillBaenInfo(key);
			}
			ObjectKit.setField(obj, fieldName, tmpObj);
		} else if(DataType.isInteger(typeCls) || DataType.isIntegerObject(typeCls)) {
			ObjectKit.setField(obj, fieldName, getIntValue(key));
		} else if(DataType.isLong(typeCls) || DataType.isLongObject(typeCls)) {
			ObjectKit.setField(obj, fieldName, getLongValue(key));
		} else if(DataType.isFloat(typeCls) || DataType.isFloatObject(typeCls)) {
			ObjectKit.setField(obj, fieldName, getFloatValue(key));
		} else if(DataType.isDouble(typeCls) || DataType.isDoubleObject(typeCls)) {
			ObjectKit.setField(obj, fieldName, getDoubleValue(key));
		} else if(DataType.isListType(typeCls) || DataType.isSetType(typeCls)){
			List list = null;
			ParameterizedType paramType = (ParameterizedType)field.getGenericType();
			Type[] paramTypes = paramType.getActualTypeArguments();
			String typeName = (paramTypes[0].toString().substring(6, paramTypes[0].toString().length()));
			Class<?> clazz = ObjectKit.newInstance(typeName).getClass();
			if(tmpObj instanceof String){
				list = JSON.parseArray(tmpObj+"", clazz);
			} else {
				list =  JSON.parseArray(JSON.toJSONString(tmpObj), clazz);
			}
			ObjectKit.setField(obj, fieldName, list);
		}  else if(DataType.isMapType(typeCls)){
			Map map =  null;
			if(tmpObj instanceof String){
				map = JSON.parseObject(tmpObj+"", Map.class);
			} else {
				map =  JSON.parseObject(JSON.toJSONString(tmpObj), Map.class);
			}
			ObjectKit.setField(obj, fieldName, map);
		}else if (typeCls.equals(Date.class)) {
			String format = "";
			String dateString = getValue(fieldName);
			if (dateString.length() == 10) { // 1979-07-31
				format = "yyyy-MM-dd";
			} else if (dateString.length() == 19) { // 1979-07-31 18:18:18
				format = "yyyy-MM-dd HH:mm:ss";
			}
			SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.getDefault());
			Date d = sdf.parse(dateString, new ParsePosition(0));
			ObjectKit.setField(obj, key, d);
		} else {
			printFillBaenInfo(field.getName());
		}
	}

	private void printFillBaenInfo(String fieldName) {
		logger.warn("字段【 " + fieldName + " 】， 请自行处理");
	}

	/**
	 * 根据key取请求值，并将数据转换为int返回
	 * 
	 * @param key
	 *            请求参数的key
	 * @return 如果值为空或转换异常时，返回-1
	 */
	protected int getIntValue(String key) {
		String value = getValue(key);
		if (ToolsKit.isNotEmpty(value)) {
			try {
				return Integer.parseInt(value);
			} catch (Exception e) {
				throw new ServiceException(e.getMessage(), e);
			}
		}
		return -1;
	}

	/**
	 * 根据key取请求值，并将数据转换为long返回
	 * 
	 * @param key
	 *            请求参数的key
	 * @return 如果值为空或转换异常时，返回-1
	 */
	protected long getLongValue(String key) {
		String value = getValue(key);
		if (ToolsKit.isNotEmpty(value)) {
			try {
				return Long.parseLong(value);
			} catch (Exception e) {
				throw new ServiceException(e.getMessage(), e);
			}
		}
		return -1l;
	}

	/**
	 * 根据key取请求值，并将数据转换为float返回
	 * 
	 * @param key
	 *            请求参数的key
	 * @return 如果值为空或转换异常时，返回-1
	 */
	protected float getFloatValue(String key) {
		String value = getValue(key);
		if (ToolsKit.isNotEmpty(value)) {
			try {
				return Float.parseFloat(value);
			} catch (Exception e) {
				throw new ServiceException(e.getMessage(), e);
			}
		}
		return -1f;
	}

	/**
	 * 根据key取请求值，并将数据转换为double返回
	 * 
	 * @param key
	 *            请求参数的key
	 * @return 如果值为空或转换异常时，返回-1
	 */
	protected double getDoubleValue(String key) {
		String value = getValue(key);
		if (ToolsKit.isNotEmpty(value)) {
			try {
				return Double.parseDouble(value);
			} catch (Exception e) {
				throw new ServiceException(e.getMessage(), e);
			}
		}
		return -1d;
	}

	/**
	 * 根据key取请求值，并将数据转换为Date返回
	 * 
	 * @param key
	 *            请求参数的key
	 * @return 如果值为空或转换异常时，返回null
	 */
	protected Date getDateValue(String key) {
		String value = getValue(key);
		if (ToolsKit.isNotEmpty(value)) {
			try {
				long millisecond = Long.parseLong(value);
				Date date = new Date();
				date.setTime(millisecond);
				return date;
			} catch (Exception ex) {
				try {
					return ToolsKit.parseDate(value);
				} catch (Exception e) {
					return null;
				}
			}
		}
		return null;
	}

	protected String getCookie(String name) {
		Cookie cookie = getCookieObject(name);
		return cookie != null ? cookie.getValue() : "";
	}

	private Cookie getCookieObject(String name) {
		Cookie[] cookies = request.getCookies();
		if (ToolsKit.isNotEmpty(cookies))
			for (Cookie cookie : cookies)
				if (cookie.getName().equals(name))
					return cookie;
		return null;
	}
	
	/**
	 * 是否是手机登录
	 * @return		如果是手机登录则返回true
	 */
	public boolean isPhoneLogin() {
		String userAgent = request.getHeader(HttpHeaders.USER_AGENT);
		if(ToolsKit.isEmpty(userAgent)){
			throw new ServiceException("request header useragent is empty!");
		}
		userAgent = userAgent.toLowerCase();
		boolean isPhoneLogin = false;
		for(String terminal : TerminalArray){
			if(userAgent.indexOf(terminal.toLowerCase()) > -1){
				isPhoneLogin = true;
				break;
			}
		}
		if(!isPhoneLogin){
			if(userAgent.toLowerCase().indexOf("applewebkit") > -1 && 
					userAgent.toLowerCase().indexOf("linux") > -1 ){
				isPhoneLogin = true;
			}
		}
		return isPhoneLogin;
	}

	// /**
	// * 添加http://file.sythealth.com在指定的字段值前
	// * @param coll
	// * @param fieldNames
	// */
	// @SuppressWarnings("unchecked")
	// protected void addFileHost(Object targetObj, String... fieldNames) {
	// if(!"oss".equalsIgnoreCase(Config.getUploadFileSite())) return;
	// if(targetObj instanceof Collection){
	// Collection coll = (Collection)targetObj;
	// for(Iterator it = coll.iterator(); it.hasNext();){
	// Object obj = it.next();
	// fillValue2Field(obj, "", fieldNames);
	// }
	// } else {
	// fillValue2Field(targetObj, "", fieldNames);
	// }
	//
	// }

	// private void fillValue2Field(Object obj, String extThumbnail, String...
	// fieldNames) {
	// Map<String, Object> map = ObjectKit.getFieldMap(obj);
	// for(String fieldName : fieldNames){
	// String imgUri = map.get(fieldName)+"";
	// if(ToolsKit.isNotEmpty(imgUri) && imgUri.indexOf("http://") == -1){
	// imgUri = imgUri.startsWith("/") ? imgUri : "/" + imgUri + extThumbnail;
	// ObjectKit.setField(obj, fieldName, Config.getFileHostSite() + imgUri);
	// }
	// }
	// }

	// /**
	// * 添加http://thumbnail.sythealth.com在指定的字段值前
	// * @param coll
	// * @param fieldNames
	// */
	// @SuppressWarnings("unchecked")
	// protected void addThumbnailHost(Object targetObj, String... fieldNames) {
	// addThumbnailHost2(targetObj, Config.getThumbnailHostSiteExt(),
	// fieldNames);
	// }
	// @SuppressWarnings("unchecked")
	// protected void addThumbnailHost2(Object targetObj, String extThumbnail,
	// String... fieldNames) {
	// if(!"oss".equalsIgnoreCase(Config.getUploadFileSite())) return;
	// if(targetObj instanceof Collection){
	// Collection coll = (Collection)targetObj;
	// for(Iterator it = coll.iterator(); it.hasNext();){
	// Object obj = it.next();
	// fillValue2Field(obj, extThumbnail, fieldNames);
	// }
	// } else {
	// fillValue2Field(targetObj, extThumbnail, fieldNames);
	// }
	// }

	protected boolean validateCpatcha(String inputRandomCode) {
		if (ToolsKit.isEmpty(inputRandomCode))
			return false;
		inputRandomCode = new String(Encodes.encodeHex(inputRandomCode.toLowerCase().getBytes()));
		return inputRandomCode.equalsIgnoreCase(getCookie("FastMvcCaptcha"));
	}

	protected void createToken() {
		TokenManager.createToken(this, Config.getTokenName(), (int) Config.getTokenTimeOut());
	}

	protected boolean validateToken() {
		return TokenManager.validateToken(this, Config.getTokenName());
	}

	/**
	 * 验证是否为duang框架发出的请求
	 * 不建议使用，请使用DuangRequestHandle来处理
	 * 
	 * @return 返回true则为安全请求
	 */
	@Deprecated
	protected boolean isDuangRequest() {
		String userAgentStr = request.getHeader(HttpHeaders.USER_AGENT);
		String versionString = userAgentStr.substring(userAgentStr.indexOf("/")+1, userAgentStr.indexOf("(")).replace(".","");
		int version = 0;
		try{version = Integer.parseInt(versionString) ;} catch(Exception e) {};
		if(version == 0) return false;
		if (version >= 200) {
			String authStr = request.getHeader(HttpHeaders.AUTHORIZATION);
			if (ToolsKit.isEmpty(authStr))
				return false;
			long requestTime = Long.parseLong(request.getHeader(HttpHeaders.DATE));
			if ((System.currentTimeMillis() - requestTime) > 10000) {
				logger.debug("the request time is more than 10 seconds");
				return false;
			}
			return HttpUtil.isDuangAuthorizAtionSignKey(authStr);
		} else {
			return HttpUtil.isDuangUserAgentSignKey(userAgentStr);
		}
	}

	/**
	 * 新增
	 */
	@Ignore
	public  void add(){}

	/**
	 * 编辑
	 */
	@Ignore
	public void edit(){}

	/**
	 * 删除
	 */
	@Ignore
	public void delete(){}

	/**
	 * 查找
	 */
	@Ignore
	public void find(){}

	/**
	 * 列表
	 */
	@Ignore
	public void list(){}

	/**
	 * 主页
	 */
	@Ignore
	public void index(){}

	/**
	 * 保存
	 */
	@Ignore
	public void save(){}

}
